#include "app_vent_heat.h"

#include <string.h>

static result_e app_vent_heat_apply_mode(vent_heat_mode_e mode);
static void     app_vent_heat_apply_interlock(vent_heat_mode_e mode);

/* 通风加热系统实例 */
static vent_heat_system_t vent_heat_system;

/**
 * @brief 初始化通风加热系统
 *
 * @return result_e 初始化结果, RESULT_STATUS_OK表示成功, 其他值表示失败
 */
result_e app_vent_heat_init(void)
{
    result_e result = RESULT_STATUS_OK;

    /* 初始化风扇系统 */
    result = inf_fan_init();
    if (result != RESULT_STATUS_OK) {
        return result;
    }
    inf_fan_set_system_enable(true);

    /* 初始化加热垫系统 */
    result = inf_heat_init();
    if (result != RESULT_STATUS_OK) {
        return result;
    }
    inf_heat_set_system_enable(true);

    /* 初始化系统状态 */
    memset(&vent_heat_system, 0, sizeof(vent_heat_system_t));

    vent_heat_system.current_mode            = VENT_HEAT_MODE_OFF;
    vent_heat_system.current_status          = VENT_HEAT_STATUS_IDLE;
    vent_heat_system.initialized             = true;
    vent_heat_system.config.enable_interlock = true; /* 默认启用互锁 */

    return RESULT_STATUS_OK;
}

/**
 * @brief 设置通风加热模式
 *
 * @param   mode        要设置的模式
 * @return  result_e    设置结果, RESULT_STATUS_OK表示成功, 其他值表示失败
 */
result_e app_vent_heat_set_mode(vent_heat_mode_e mode)
{
    if (mode >= VENT_HEAT_MODE_MAX) {
        return RESULT_STATUS_INVALID_PARAM;
    }

    /* 系统使能检查 */
    if (!vent_heat_system.initialized && mode != VENT_HEAT_MODE_OFF) {
        return RESULT_STATUS_NOT_INITIALIZED;
    }

    /* 保存当前模式 */
    vent_heat_mode_e old_mode     = vent_heat_system.current_mode;
    vent_heat_system.current_mode = mode;

    /* 应用新模式 */
    result_e result = app_vent_heat_apply_mode(mode);
    if (result != RESULT_STATUS_OK) {
        /* 应用模式失败，恢复旧模式 */
        vent_heat_system.current_mode = old_mode;
        return result;
    }

    /* 如果启用了互锁, 设置互锁状态 */
    if (vent_heat_system.config.enable_interlock) {
        app_vent_heat_apply_interlock(mode);
    }

    return result;
}

/**
 * @brief 获取当前通风加热模式
 *
 * @return vent_heat_mode_e 当前模式
 */
vent_heat_mode_e app_vent_heat_get_mode(void) { return vent_heat_system.current_mode; }

/**
 * @brief 处理通风加热系统, 需要在调度器中调度, 50~100ms调度一次, 实测100ms就可以
 *
 */
void app_vent_heat_handle(void)
{
    if (!vent_heat_system.initialized) {
        return;
    }

    inf_fan_handle();
    inf_heat_handle();

    /* 检查故障 */
    bool has_fault = false;

    /* 检查风扇故障 */
    for (uint8_t i = 0; i < FAN_IDX_MAX; ++i) {
        if (inf_fan_get_fault((fan_idx_e)i) != FAN_FAULT_NONE) {
            has_fault = true;
            break;
        }
    }

    /* 检查加热垫故障 */
    for (uint8_t i = 0; i < HEAT_IDX_MAX; ++i) {
        if (inf_heat_get_fault((heat_idx_e)i) != HEAT_FAULT_NONE) {
            has_fault = true;
            break;
        }
    }

    /* 更新系统状态 */
    if (has_fault) {
        vent_heat_system.current_status = VENT_HEAT_STATUS_FAULT;
        /* 故障时强制切换到OFF模式 */
        app_vent_heat_set_mode(VENT_HEAT_MODE_OFF);
    }

    // TODO 其他处理
}

/**
 * @brief 应用互锁
 *
 * @param   mode 当前的模式
 */
static void app_vent_heat_apply_interlock(vent_heat_mode_e mode)
{
    if (mode >= VENT_HEAT_MODE_LOW_HEAT && mode <= VENT_HEAT_MODE_HI_HEAT) {
        /* 加热模式：阻塞风扇 */
        inf_fan_check_interlock(FAN_IDX_FANL, true);
        inf_heat_check_interlock(HEAT_IDX_HEATL, false);
    }
    else if (mode >= VENT_HEAT_MODE_LOW_COOL && mode <= VENT_HEAT_MODE_HI_COOL) {
        /* 通风模式：阻塞加热 */
        inf_heat_check_interlock(HEAT_IDX_HEATL, true);
        inf_fan_check_interlock(FAN_IDX_FANL, false);
    }
    else {
        /* OFF模式：清除所有互锁 */
        inf_fan_check_interlock(FAN_IDX_FANL, false);
        inf_heat_check_interlock(HEAT_IDX_HEATL, false);
    }
}

/**
 * @brief 应用通风加热模式
 *
 * @param   mode        要应用的模式
 * @return  result_e    应用结果, RESULT_STATUS_OK表示成功, 其他值表示失败
 */
static result_e app_vent_heat_apply_mode(vent_heat_mode_e mode)
{
    /* 根据模式控制风扇和加热垫 */
    switch (mode) {
    case VENT_HEAT_MODE_OFF:
        /* 关闭所有功能 */
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_CLOSE);
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_CLOSE);
        vent_heat_system.current_status = VENT_HEAT_STATUS_IDLE;
        break;

    case VENT_HEAT_MODE_LOW_HEAT:
        /* 低档加热：关闭风扇，启动低档加热 */
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_CLOSE);
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_LOW);
        vent_heat_system.current_status = VENT_HEAT_STATUS_HEATING;
        break;

    case VENT_HEAT_MODE_MID_HEAT:
        /* 中档加热：关闭风扇，启动中档加热 */
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_CLOSE);
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_MID);
        vent_heat_system.current_status = VENT_HEAT_STATUS_HEATING;
        break;

    case VENT_HEAT_MODE_HI_HEAT:
        /* 高档加热：关闭风扇，启动高档加热 */
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_CLOSE);
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_HIGH);
        vent_heat_system.current_status = VENT_HEAT_STATUS_HEATING;
        break;

    case VENT_HEAT_MODE_LOW_COOL:
        /* 低档通风：关闭加热，启动低档风扇 */
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_CLOSE);
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_LOW);
        vent_heat_system.current_status = VENT_HEAT_STATUS_COOLING;
        break;

    case VENT_HEAT_MODE_MID_COOL:
        /* 中档通风：关闭加热，启动中档风扇 */
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_CLOSE);
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_MID);
        vent_heat_system.current_status = VENT_HEAT_STATUS_COOLING;
        break;

    case VENT_HEAT_MODE_HI_COOL:
        /* 高档通风：关闭加热，启动高档风扇 */
        inf_heat_set_gear(HEAT_IDX_HEATL, HEAT_GEAR_CLOSE);
        inf_fan_set_gear(FAN_IDX_FANL, FAN_GEAR_HIGH);
        vent_heat_system.current_status = VENT_HEAT_STATUS_COOLING;
        break;

    default: return RESULT_STATUS_INVALID_PARAM;
    }

    return RESULT_STATUS_OK;
}
